package com.lds.sign_sdk.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.lang.invoke.MethodHandles;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;
import java.util.UUID;

/**
 * @Date 2022/1/13
 * @Time 11:10
 * @Author liudongs
 * @E-mail liudongs@aliyun.com
 * @Version 1.0.0
 * @Description AES 对称算法加密/解密工具类
 * 最为推荐使用
 **/
public class AESUtils {
    private static final String KEY_ALGORITHM = "AES";
    private static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());

    /**
     * @desc: AES对称-加密操作
     * @param keyStr 进行了Base64编码的秘钥
     * @param data 需要进行加密的原文
     * @return String 数据密文，加密后的数据，进行了Base64的编码
     */
    public static String encrypt2Str(String keyStr, String data) throws Exception {
        // 转换密钥
        Key key = new SecretKeySpec(Base64.getDecoder().decode(keyStr), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        // 加密
        cipher.init(Cipher.ENCRYPT_MODE, key);
        byte[] result = cipher.doFinal(data.getBytes());
        return Base64.getEncoder().encodeToString(result);
    }

    /**
     * @desc: AES对称-解密操作
     * @param keyStr 进行了Base64编码的秘钥
     * @param data 需要解密的数据（数据必须是通过AES进行加密后，对加密数据Base64编码的数据）
     * @return String 返回解密后的原文
     */
    public static String decrypt2Str(String keyStr, String data) throws Exception {
        // 转换密钥
        Key key = new SecretKeySpec(Base64.getDecoder().decode(keyStr), KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        // 解密
        cipher.init(Cipher.DECRYPT_MODE, key);
        byte[] result = cipher.doFinal(Base64.getDecoder().decode(data));
        return new String(result);
    }

    /**
     * @desc: 生成AES的秘钥，秘钥进行了Base64编码的字符串
     * @return String 对生成的秘钥进行了Base64编码的字符串
     */
    public static String keyGenerate() throws Exception {
        // 生成密钥
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
        keyGenerator.init(new SecureRandom());
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] keyBytes = secretKey.getEncoded();
        return Base64.getEncoder().encodeToString(keyBytes);
    }

    public AESUtils() {
    }

    private static byte[] encrypt(String key, String content) {
        byte[] rawKey = genKey(key.getBytes());

        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(rawKey, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(1, secretKeySpec);
            byte[] encypted = cipher.doFinal(content.getBytes());
            return encypted;
        } catch (Exception var6) {
            return null;
        }
    }

    public static String encryptBase64(String key, String content) {
        byte[] encrypt = encrypt(key, content);
        return Base64.getEncoder().encodeToString(encrypt);
    }

    public static String decryptBase64(String key, String content) {
        byte[] decodeContent = Base64.getDecoder().decode(content);
        return decrypt(key, decodeContent);
    }

    private static String decrypt(String key, byte[] encrypted) {
        byte[] rawKey = genKey(key.getBytes());

        try {
            SecretKeySpec secretKeySpec = new SecretKeySpec(rawKey, KEY_ALGORITHM);
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(2, secretKeySpec);
            byte[] decrypted = cipher.doFinal(encrypted);
            return new String(decrypted);
        } catch (Exception var6) {
            logger.debug("解密失败以为你返回原值");
            return "";
        }
    }

    private static byte[] genKey(byte[] seed) {
        byte[] rawKey = null;

        try {
            KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(seed);
            kgen.init(128, secureRandom);
            SecretKey secretKey = kgen.generateKey();
            rawKey = secretKey.getEncoded();
        } catch (NoSuchAlgorithmException var5) {
        }

        return rawKey;
    }

    public static void main(String[] args) {
        String key = UUID.randomUUID().toString();
        System.out.println(key);
        String clearPwd = "123456";
        byte[] encryptedByteArr = encrypt(key, clearPwd);
        String encryptedPwd = Base64.getEncoder().encodeToString(encryptedByteArr);
        System.out.println(encryptedPwd);
        byte[] decode = Base64.getDecoder().decode(encryptedPwd);
        String decryptedPwd = decrypt(key, decode);
        System.out.println(decryptedPwd);
    }
}
